package com.lifeverse.service;

import com.lifeverse.entity.BehaviorPattern;
import com.lifeverse.entity.LearningExperience;
import com.lifeverse.repository.BehaviorPatternRepository;
import com.lifeverse.repository.LearningExperienceRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 自适应参数调整服务
 * 基于历史数据和性能反馈自动调整系统参数
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class AdaptiveParameterService {

    private final BehaviorPatternRepository behaviorPatternRepository;
    private final LearningExperienceRepository learningExperienceRepository;

    /**
     * 调整学习参数
     */
    @Transactional
    public ParameterAdjustmentResult adjustLearningParameters(Long lifeEntityId) {
        log.info("开始为生命体 {} 调整学习参数", lifeEntityId);
        
        try {
            // 获取最近的学习数据
            LocalDateTime since = LocalDateTime.now().minus(30, ChronoUnit.DAYS);
            List<LearningExperience> recentExperiences = learningExperienceRepository
                    .findRecentExperiences(lifeEntityId, since);
            
            if (recentExperiences.isEmpty()) {
                return new ParameterAdjustmentResult(false, "缺少学习数据");
            }
            
            ParameterAdjustmentResult result = new ParameterAdjustmentResult(true, "参数调整完成");
            
            // 调整学习率
            double newLearningRate = calculateOptimalLearningRate(recentExperiences);
            result.addAdjustment("learning_rate", newLearningRate);
            
            // 调整难度偏好
            double newDifficultyPreference = calculateOptimalDifficulty(recentExperiences);
            result.addAdjustment("difficulty_preference", newDifficultyPreference);
            
            // 调整重复学习频率
            double newRepetitionFrequency = calculateOptimalRepetition(recentExperiences);
            result.addAdjustment("repetition_frequency", newRepetitionFrequency);
            
            log.info("学习参数调整完成，调整了 {} 个参数", result.getAdjustments().size());
            return result;
            
        } catch (Exception e) {
            log.error("调整学习参数失败", e);
            return new ParameterAdjustmentResult(false, "调整失败: " + e.getMessage());
        }
    }

    /**
     * 调整决策参数
     */
    @Transactional
    public ParameterAdjustmentResult adjustDecisionParameters(Long lifeEntityId) {
        log.info("开始为生命体 {} 调整决策参数", lifeEntityId);
        
        try {
            // 获取决策相关的行为模式
            List<BehaviorPattern> decisionPatterns = behaviorPatternRepository
                    .findByLifeEntityIdAndPatternType(lifeEntityId, 
                            com.lifeverse.entity.enums.PatternType.DECISION);
            
            if (decisionPatterns.isEmpty()) {
                return new ParameterAdjustmentResult(false, "缺少决策模式数据");
            }
            
            ParameterAdjustmentResult result = new ParameterAdjustmentResult(true, "决策参数调整完成");
            
            // 调整决策置信度阈值
            double newConfidenceThreshold = calculateOptimalConfidenceThreshold(decisionPatterns);
            result.addAdjustment("decision_confidence_threshold", newConfidenceThreshold);
            
            // 调整决策时间限制
            double newTimeLimit = calculateOptimalDecisionTime(decisionPatterns);
            result.addAdjustment("decision_time_limit", newTimeLimit);
            
            // 调整风险偏好
            double newRiskPreference = calculateOptimalRiskPreference(decisionPatterns);
            result.addAdjustment("risk_preference", newRiskPreference);
            
            log.info("决策参数调整完成");
            return result;
            
        } catch (Exception e) {
            log.error("调整决策参数失败", e);
            return new ParameterAdjustmentResult(false, "调整失败: " + e.getMessage());
        }
    }

    /**
     * 调整交互参数
     */
    @Transactional
    public ParameterAdjustmentResult adjustInteractionParameters(Long lifeEntityId) {
        log.info("开始为生命体 {} 调整交互参数", lifeEntityId);
        
        try {
            List<BehaviorPattern> interactionPatterns = behaviorPatternRepository
                    .findByLifeEntityIdAndPatternType(lifeEntityId, 
                            com.lifeverse.entity.enums.PatternType.INTERACTION);
            
            if (interactionPatterns.isEmpty()) {
                return new ParameterAdjustmentResult(false, "缺少交互模式数据");
            }
            
            ParameterAdjustmentResult result = new ParameterAdjustmentResult(true, "交互参数调整完成");
            
            // 调整社交活跃度
            double newSocialActivity = calculateOptimalSocialActivity(interactionPatterns);
            result.addAdjustment("social_activity_level", newSocialActivity);
            
            // 调整协作倾向
            double newCollaborationTendency = calculateOptimalCollaboration(interactionPatterns);
            result.addAdjustment("collaboration_tendency", newCollaborationTendency);
            
            log.info("交互参数调整完成");
            return result;
            
        } catch (Exception e) {
            log.error("调整交互参数失败", e);
            return new ParameterAdjustmentResult(false, "调整失败: " + e.getMessage());
        }
    }

    // 私有计算方法
    private double calculateOptimalLearningRate(List<LearningExperience> experiences) {
        double avgEfficiency = experiences.stream()
                .mapToDouble(LearningExperience::getEfficiency)
                .average().orElse(0.5);
        
        // 基于效率调整学习率
        if (avgEfficiency > 0.8) {
            return 0.8; // 高效率时可以提高学习率
        } else if (avgEfficiency < 0.4) {
            return 0.3; // 低效率时降低学习率
        } else {
            return 0.5; // 默认学习率
        }
    }

    private double calculateOptimalDifficulty(List<LearningExperience> experiences) {
        double avgDifficulty = experiences.stream()
                .mapToDouble(LearningExperience::getDifficultyLevel)
                .average().orElse(5.0);
        
        double successRate = experiences.stream()
                .mapToDouble(e -> e.getOutcome().name().contains("SUCCESS") ? 1.0 : 0.0)
                .average().orElse(0.5);
        
        // 根据成功率调整难度偏好
        if (successRate > 0.8) {
            return Math.min(10.0, avgDifficulty + 1); // 成功率高时增加难度
        } else if (successRate < 0.4) {
            return Math.max(1.0, avgDifficulty - 1); // 成功率低时降低难度
        } else {
            return avgDifficulty;
        }
    }

    private double calculateOptimalRepetition(List<LearningExperience> experiences) {
        double avgRetention = experiences.stream()
                .mapToDouble(LearningExperience::getRetentionRate)
                .average().orElse(0.7);
        
        // 基于保持率调整重复频率
        if (avgRetention < 0.6) {
            return 0.8; // 保持率低时增加重复频率
        } else if (avgRetention > 0.9) {
            return 0.3; // 保持率高时减少重复频率
        } else {
            return 0.5;
        }
    }

    private double calculateOptimalConfidenceThreshold(List<BehaviorPattern> patterns) {
        double avgConfidence = patterns.stream()
                .mapToDouble(BehaviorPattern::getConfidenceScore)
                .average().orElse(0.6);
        
        return Math.max(0.3, Math.min(0.9, avgConfidence - 0.1));
    }

    private double calculateOptimalDecisionTime(List<BehaviorPattern> patterns) {
        // 基于模式频率估算最优决策时间
        double avgFrequency = patterns.stream()
                .mapToDouble(BehaviorPattern::getFrequency)
                .average().orElse(10.0);
        
        return Math.max(30.0, Math.min(300.0, 60.0 / Math.log(avgFrequency + 1)));
    }

    private double calculateOptimalRiskPreference(List<BehaviorPattern> patterns) {
        // 基于异常分数调整风险偏好
        double avgAnomalyScore = patterns.stream()
                .filter(p -> p.getAnomalyScore() != null)
                .mapToDouble(BehaviorPattern::getAnomalyScore)
                .average().orElse(0.3);
        
        return Math.max(0.1, Math.min(0.9, 0.5 - avgAnomalyScore));
    }

    private double calculateOptimalSocialActivity(List<BehaviorPattern> patterns) {
        double avgFrequency = patterns.stream()
                .mapToDouble(BehaviorPattern::getFrequency)
                .average().orElse(5.0);
        
        return Math.max(0.1, Math.min(1.0, avgFrequency / 20.0));
    }

    private double calculateOptimalCollaboration(List<BehaviorPattern> patterns) {
        // 基于交互模式的成功率调整协作倾向
        long successfulPatterns = patterns.stream()
                .filter(p -> p.getConfidenceScore() > 0.7)
                .count();
        
        double successRate = patterns.isEmpty() ? 0.5 : (double) successfulPatterns / patterns.size();
        return Math.max(0.2, Math.min(0.9, successRate));
    }

    // 结果类
    public static class ParameterAdjustmentResult {
        private boolean success;
        private String message;
        private Map<String, Double> adjustments = new HashMap<>();
        private LocalDateTime adjustmentTime = LocalDateTime.now();

        public ParameterAdjustmentResult(boolean success, String message) {
            this.success = success;
            this.message = message;
        }

        public void addAdjustment(String parameter, double value) {
            adjustments.put(parameter, value);
        }

        // getters and setters
        public boolean isSuccess() { return success; }
        public void setSuccess(boolean success) { this.success = success; }
        public String getMessage() { return message; }
        public void setMessage(String message) { this.message = message; }
        public Map<String, Double> getAdjustments() { return adjustments; }
        public void setAdjustments(Map<String, Double> adjustments) { this.adjustments = adjustments; }
        public LocalDateTime getAdjustmentTime() { return adjustmentTime; }
        public void setAdjustmentTime(LocalDateTime adjustmentTime) { this.adjustmentTime = adjustmentTime; }
    }
}